Skip to content

Add relabel option to secrets #1210

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Add relabel option to secrets #1210

wants to merge 1 commit into from

Conversation

jarovo
Copy link

@jarovo jarovo commented May 18, 2025

On selinux enabled system, the secrets cannot be read without proper relabeling or correct policy being set.

This patch enables user to instruc podman-copose to use :z or :Z --volume options to make podman relabel the file under bind-mount.

More info here:
https://unix.stackexchange.com/questions/728801/host-wide-consequences-of-setting-selinux-z-z-option-on-container-bind-mounts?rq=1

Contributor Checklist:

If this PR adds a new feature that improves compatibility with docker-compose, please add a link
to the exact part of compose spec that the PR touches.

For any user-visible change please add a release note to newsfragments directory, e.g.
newsfragments/my_feature.feature. See newsfragments/README.md for more details.

All changes require additional unit tests.

@p12tic
Copy link
Collaborator

p12tic commented May 19, 2025

Is this part of compose spec? Seems that no. In such case it should be named with x-podman. prefix and documentation added to docs/Extensions.md. I also don't think that relabel is clear name, though I don't have better suggestions at this time.

@jarovo
Copy link
Author

jarovo commented May 19, 2025

Is this part of compose spec? Seems that no. In such case it should be named with x-podman. prefix and documentation added to docs/Extensions.md. I also don't think that relabel is clear name, though I don't have better suggestions at this time.

Thanks for the suggestion. It is not a part of the docker-compose spec and i don't know about any equivalent option there.

What about changig this to zzmount?

@jarovo
Copy link
Author

jarovo commented May 23, 2025

Similar issue -- with volumes in docker was discussed here with a conclusion that the best approach is setting the se-linux labels on host.

moby/moby#32579 (comment)

Should podman-compose or podman or something on the host relabel the files containing the secrets automagically?

@jarovo jarovo force-pushed the main branch 2 times, most recently from eede052 to d8d852f Compare May 23, 2025 11:29
@jarovo jarovo marked this pull request as ready for review May 23, 2025 11:59
@p12tic
Copy link
Collaborator

p12tic commented May 23, 2025

Sorry for delay, I will get back to this.

custom-secret:
x-podman.relabel: z
```
For explanations of these extensions, please refer to the [PR discussion](https://github.com/containers/podman-compose/pull/1210).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs proper documentation, not link to PR. Copy if needed.

```yml
secrets:
custom-secret:
x-podman.relabel: z
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to borrow values of the podman mount option (https://docs.podman.io/en/latest/markdown/podman-run.1.html#mount-type-type-type-specific-option). Bind and glob support relabel option with shared and private values possible.

@p12tic
Copy link
Collaborator

p12tic commented May 24, 2025

I looked into how podman handles relabeling and it does have relabel suboption of some of its option which does similar things. So I think current naming is great. Let's rename zZ to shared and private. Other than that, looks great, thank you.

@@ -302,6 +302,17 @@ async def test_secret_target_matches_secret_name_secret_type_not_env(self):
"file_secret",
repo_root() + "/test_dirname/my_secret:/run/secrets/file_secret:ro,rprivate,rbind",
),
(
"relabel",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need 2 cases: for private and shared relabel, because we'll be translating things to what podman understands in this context.

@p12tic
Copy link
Collaborator

p12tic commented May 24, 2025

static checks test fails due to formatting. to fix it, install test-requirements.txt in your virtualenv and run ruff format and ruff check --fix

@jarovo jarovo marked this pull request as draft May 25, 2025 03:38
@jarovo
Copy link
Author

jarovo commented May 25, 2025

I am searching for proper doc for the relabel option. Ther are
Red hat labs speaking about them. There is a blog posts from other geek and here.

It should be noted that the mount options related to shared subtrees uses the words shared and private, but I believe they have different meaning. This needs further clarification and possibly some new article for clarification of these terms as they are seem similar so I am marking this PR as a draft to make sure the we have the proper doc.

@jarovo
Copy link
Author

jarovo commented May 25, 2025

static checks test fails due to formatting. to fix it, install test-requirements.txt in your virtualenv and run ruff format and ruff check --fix

Thanks. This helped. I really wasn't keen on reformatting the whole source (:+1:

@p12tic
Copy link
Collaborator

p12tic commented May 29, 2025

@jarovo I think that the current naming and meaning is correct. If we go by https://docs.podman.io/en/latest/markdown/podman-run.1.html#mount-type-type-type-specific-option, then we see that:

relabel=shared|private is an option for bind or glob mounts. This is the syntax allowed by --mount option.

:Z and :z is an specification accepted by --volume. However, --volume is simply a bind mount, so it eventually maps to --mount anyway. Accordingly, :zZ are direct equivalents to shared and private relabel options.

@jarovo
Copy link
Author

jarovo commented May 31, 2025

Here is the doc:
https://docs.podman.io/en/v4.4/markdown/options/volume.html

I believe :zZ are options for podman --volume option and it actually has not much to do with private or shared mount option.

Here is what mount command supports: https://www.man7.org/linux/man-pages/man8/mount.8.html note that there is no :zZ.

I think podman does the magic of relabeling the contents of the mounted filesystem subtree

I am happy with the curent state. We can merge.

@jarovo jarovo marked this pull request as ready for review May 31, 2025 16:58
@jarovo
Copy link
Author

jarovo commented Jun 1, 2025

So if I understand, there is no blocker for merging this

@jarovo
Copy link
Author

jarovo commented Jun 3, 2025

@p12tic what can I do to get this merged? Thank you.

jarovo added a commit to stashbus/stashbus that referenced this pull request Jun 3, 2025
Reflecting changes in containers/podman-compose#1210

Signed-off-by: Jaroslav Henner <1187265+jarovo@users.noreply.github.com>
@p12tic
Copy link
Collaborator

p12tic commented Jun 4, 2025

Sorry for delays, this is one of these more difficult PRs where I need to figure out more things than usual :-)

I believe :zZ are options for podman --volume option and it actually has not much to do with private or shared mount option.

But --volume option documentation starts with "Create a bind mount". I interpret that --volume is just a subset of --mount option with different syntax (https://docs.podman.io/en/v4.4/markdown/options/mount.html).

If we look into podman sources, we see that relabel=private and relabel=shared are translated to zZ in the end (see here https://github.com/containers/podman/blob/6a39f37845f5e812cb56c709694b01431f108a09/pkg/specgenutil/volumes.go#L409) and then they are handled by podman itself (https://github.com/containers/podman/blob/6a39f37845f5e812cb56c709694b01431f108a09/libpod/container_internal_common.go#L415, https://github.com/containers/podman/blob/6a39f37845f5e812cb56c709694b01431f108a09/libpod/container_internal_common.go#L3124).

@jarovo
Copy link
Author

jarovo commented Jun 4, 2025

Sorry for delays, this is one of these more difficult PRs where I need to figure out more things than usual :-)

I believe :zZ are options for podman --volume option and it actually has not much to do with private or shared mount option.
The truth is they are not available as I would expect while the :z works:

[jhenner@vydra tmp]$ rm /tmp/foo/ -rf
[jhenner@vydra tmp]$ mkdir /tmp/foo; echo Hello world > /tmp/foo/bar
[jhenner@vydra tmp]$ ll -Z foo/bar
-rw-r--r--. 1 jhenner jhenner unconfined_u:object_r:user_tmp_t:s0 12  4. čen 12.17 foo/bar
[jhenner@vydra tmp]$ podman run -v ./foo:/foo:relabel=shared alpine cat /foo/bar
Error: invalid option type "relabel=shared"
[jhenner@vydra tmp]$ ll -Z foo/bar
-rw-r--r--. 1 jhenner jhenner unconfined_u:object_r:user_tmp_t:s0 12  4. čen 12.17 foo/bar

The selinux label was not touched.

[jhenner@vydra tmp]$ podman run -v ./foo:/foo:z alpine cat /foo/bar
Hello world
[jhenner@vydra tmp]$ ll -Z foo/bar
-rw-r--r--. 1 jhenner jhenner system_u:object_r:container_file_t:s0 12  4. čen 12.17 foo/bar

Now we are talking! The files have been relabeled by something. Surely podman did this in the file you mentioned

But --volume option documentation starts with "Create a bind mount". I interpret that --volume is just a subset of --mount option with different syntax (https://docs.podman.io/en/v4.4/markdown/options/mount.html).

If we look into podman sources, we see that relabel=private and relabel=shared are translated to zZ in the end (see here https://github.com/containers/podman/blob/6a39f37845f5e812cb56c709694b01431f108a09/pkg/specgenutil/volumes.go#L409) and then they are handled by podman itself (https://github.com/containers/podman/blob/6a39f37845f5e812cb56c709694b01431f108a09/libpod/container_internal_common.go#L415, https://github.com/containers/podman/blob/6a39f37845f5e812cb56c709694b01431f108a09/libpod/container_internal_common.go#L3124).

Thanks for the sources links! I searched the options declarations in the same repo. I see :z :Z options are declared there, but nothing about :relabel=private or :relabel=shared or similar in mount_opts.go

Perhaps that is why only :z or :Z is working for me. I think the code for handling the relabel=private or relabel=shared options is an unreachable code due to lack of declaration of these options.

@p12tic
Copy link
Collaborator

p12tic commented Jun 4, 2025

I think the code for handling the relabel=private or relabel=shared options is an unreachable code

Indeed, podman tries to conform to docker API and docker only has z and Z in volume option (https://docs.docker.com/engine/storage/bind-mounts/#options-for---volume).

So most likely podman documentation is wrong.

@@ -27,6 +27,14 @@ services:

For explanations of these extensions, please refer to the [Podman Documentation](https://docs.podman.io/).

## Secrets
```yml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add:

`The following extension keys are available under secret configuration:

  • x-podman.relabel - Configure SELinux relabeling

For example, the following configures custom-secret to use mount with private and unshared content.

selinux_mount_option = selinux_relabel_to_mount_option_map[x_podman_relabel]
except KeyError as exc:
raise ValueError(
f'ERORR: Run secret "{secret_name} has invalid "relabel" option related '
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo in ERORR


selinux_relabel_to_mount_option_map = {None: "", "z": ",z", "Z": ",Z"}
try:
selinux_mount_option = selinux_relabel_to_mount_option_map[x_podman_relabel]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe immediately do mount_options += selinux_relabel_to_mount_option_map[x_podman_relabel]

Copy link
Collaborator

@p12tic p12tic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall, I had several comments. Please squash your commits into one as all subsequent commits are fixing the first commit.

On selinux enabled system, the secrets cannot be read without proper
relabeling or correct policy being set.

This patch enables user to instruc podman-copose to use :z or :Z mount
options to make podman relabel the file under bind-mount.

More info here:
https://unix.stackexchange.com/questions/728801/host-wide-consequences-of-setting-selinux-z-z-option-on-container-bind-mounts?rq=1

Signed-off-by: Jaroslav Henner <1187265+jarovo@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants